<template>
	<view class="transfer" :dataInfo="dataInfo" :change:dataInfo="renderjs.getdataInfo">
		<HeaderBar title="转账" showBack fixed />
		<view class="contentBox" :timeId="timeId" :change:timeId="renderjs.send">
			<view class="cell">
				<view class="top">
					<view class="text">
						收款地址
					</view>
					<view class="seletWallet" @tap="selectWallet">
						<text>选择钱包</text>
						<text class="iconfont icon-youjiantou"></text>
					</view>
				</view>
				<view class="bottom">
					<view class="inputBox">
						<view class="addressIpt">
							<uni-easyinput type="textarea" v-model="toAddress" :inputBorder="false" :trim="true"
								placeholder="输入或粘贴钱包地址" class="input" placeholder-style="#979797"></uni-easyinput>
							<!-- <input type="text" v-model="toAddress" 
								placeholder="输入或粘贴钱包地址" /> -->
						</view>
						<!-- <view class="right">
							<image src="/static/images/home/san.png" mode="widthFix" style="width: 44upx;height: 44upx;"
								@tap="scanQRCode"></image>
						</view> -->
					</view>
				</view>
			</view>
			<view class="cell">
				<view class="top">
					<view class="text number">
						转账金额
					</view>
					<view class="seletWallet" @tap="selectToken">
						<text v-if="token">{{token.tokensymbol}}</text>
						<text class="iconfont icon-youjiantou"></text>
					</view>
				</view>
				<view class="bottom border">
					<view class="inputBox">
						<view class="">
							<input type="digit" v-model="number" class="input" placeholder-style="#979797"
								placeholder="请输入数量" @blur="blur" />
						</view>
						<view class="right">
							<view class="all" @tap="all">
								全部
							</view>
						</view>
					</view>
				</view>
				<view class="balacne">
					<view class="text">
						钱包金额
					</view>
				
					<view class="number">
						 {{balance}} <text v-if="token">{{token.tokensymbol}}</text>
					</view>
				</view>
			</view>
			<!-- <view class="fees" v-if="chainInfo.chainType=='ETH'">
				 {{$utils.toTwoDecimalDown(balance)}}
				<view class="title">
					<view class="">
						网络费
					</view>
					<image src="/static/images/home/helpGray.png" class="icon" mode=""></image>
				</view>
				<view class="content">
					<view class="title">
						预计
					</view>
					<view class="feesnumber">
						{{estimatedFee}}
					</view>
				</view>
			</view> -->
			<view class="btn" :data-toAddress="toAddress" :data-number="number" :data-balance="balance"
				@tap="renderjs.checkAddress">
				确认
			</view>
		</view>

		<uni-popup ref="popup" type="bottom" background-color="#FFFFFF" border-radius="10px 10px 0 0">
			<view class="popupTitle">
				交易详情
				<!-- <text class="iconfont icon-guanbi"></text> -->
			</view>
			<view class="numberBox">
				<view class="number">
					{{number}} <text v-if="token">{{token.tokensymbol}}</text>
				</view>
			</view>
			<view class="fromAddress">
				<view class="left">
					付款地址
				</view>
				<view class="right">
					<view class="address">
						{{address}}
					</view>
				</view>
			</view>
			<view class="toAddress borderT ">
				<view class="left">
					收款地址
				</view>
				<view class="right">
					<view class="address">
						{{toAddress}}
					</view>
					<!-- <text class="chain" v-if="name">({{name}})</text> -->
				</view>
			</view>

			<view class="toAddress borderT borderB">
				<view class="left">
					网络费
				</view>
				<view class="right">
					<view class="address" v-if="chainInfo.chainType=='ETH'">
						{{fee}} {{getTokenymbol}}
					</view>
					<view class="address" v-if="chainInfo.chainType=='TRON'">
						≈ {{fee}} TRX
					</view>
					<text class="chain" v-if="chainInfo.chainType=='ETH'">≈ Gas Limit({{gasLimit}})*Gas
						Price({{Number(Number(gasPrice).toFixed(4))}} Gwei)</text>
				</view>
			</view>
			<!-- <view class="popupBtn">
				<view class="pbtn" @tap="pass">
					确定
				</view>
			</view> -->
			<view class="popupBtn">
				<view class="pbtn quxiaopth" @tap="cancel">
					取消
				</view>
				<view class="pbtn" @tap="pass">
					确定
				</view>
			</view>
		</uni-popup>
		<PasswordPopup ref="passwordPopup" @close="close" @confirm="confirm" />
	</view>
</template>

<script>
	export default {
		data() {
			return {
				name: "",
				balance: 0,
				number: "",
				toAddress: "",
				gasPrice: "",
				gasLimit: "",
				fee: "",
				token: null,
				timeIdInfo: "",
				timeId: "",
			}
		},
		computed: {
			addressInfo() {
				return this.$store.getters.addressInfo
			},
			dataInfo() {
				return {
					rpc: this.$store.getters.getRpc,
					privateKey: this.addressInfo?.privateKey,
					chainType: this.chainInfo?.chainType,
					address: this.address,
					tokenaddress: this.token?.tokenaddress,
					ethabi: this.$config?.erc20,
					tronabi: this.$config?.tronERC20,
					password: this.addressInfo?.password,
					decimals: this.token?.tokendemail,
				}
			},
			getTokenymbol() {
				return this.$store.getters.tokensymbol
			},
			address() {
				return this.$store.getters.getAddress;
			},
			chainId() {
				return this.$store.getters.getChainId;
			},

			choinInfo() {
				return this.$store.getters.choinInfo
			},
			chainInfo() {
				return this.$store.getters.chainInfo
			},
			defaultToken() {
				return this.choinInfo && this.choinInfo.find((item) => item.tokenaddress == this.$config.defaultAddress)
			},
		},
		watch: {
			defaultToken(newValue) {
				if (newValue && !this.token) {
					this.token = newValue;
				}
			}

		},
		onLoad(options) {
			const configStr = options.token || '';
			if (configStr) {
				try {
					const token = JSON.parse(decodeURIComponent(configStr));
					this.token = token
				} catch (error) {}
			} else if (this.defaultToken) {
				this.token = this.defaultToken;
			}

		},
		mounted() {
			uni.$on("selectWallet", (wallet) => {
				this.toAddress = wallet.address
				this.name = wallet.name
			})
			uni.$on("switchToken", (token) => {
				this.token = token
			})
		},
		methods: {
			showLoad() {
				uni.showLoading({
					title: '加载中',
					mask: true,
				});
			},
			heiLoad() {
				uni.hideLoading()
			},
			cancel() {
				this.$refs.popup.close()
			},
			//获取余额回调
			getBalance(value) {
				uni.$db.update('list', {
					from: 'choinList',
					set: {
						tokennum: value
					},
					where: [{
						address: `= "${this.address}"`,
						tokenaddress: `= "${this.token.tokenaddress}"`,
					}]
				});
				this.balance = value
			},
			//获取手续费回调
			getFee(info) {
				this.gasLimit = info.gasLimit
				this.gasPrice = info.gasPrice
				this.fee = info.fee
				this.timeIdInfo = info.timeId
				this.open()
			},
			all() {
				if (this.balance) {
					this.number = this.balance
					 // this.$utils.toTwoDecimalDown(this.balance)
				}
			},
			open() {
				this.$refs.popup.open('bottom')
			},
			pass() {
				this.$refs.passwordPopup.open();
			},
			close() {
				this.$refs.passwordPopup.close()
			},
			confirm() {
				this.close()
				this.timeId = this.timeIdInfo
				this.$refs.popup.close()
				this.$refs.popup1.close()
			},
			success() {
				this.$updateWalletInfo()
				setTimeout(() => {
					uni.switchTab({
						url: '/pages/index/index', // 这里的路径是 tabBar 页面在项目中的路径
					});
				}, 2000)
			},
			hideLoad() {
				uni.hideLoading();
			},
			error(tip) {
				uni.showToast({
					title: tip,
					position: "bottom",
					icon: "none",
					duration: 2000,
				});
			},
			selectWallet() {
				uni.navigateTo({
					url: `/pages/walletList/walletList`
				})
			},
			selectToken() {
				uni.navigateTo({
					url: `/pages/tokenList/tokenList`
				})
			},
			// scanQRCode() {
			// 	uni.scanCode({
			// 		success: (res) => {
			// 			this.toAddress = res.result;
			// 			this.name = ""
			// 		},
			// 		fail: (err) => {

			// 		}
			// 	});
			// },
		}
	}
</script>
<script module="renderjs" lang="renderjs">
	export default {
		data() {
			return {
				jsLoadState: false,
				tjsLoadState: false,
				dataLoadState: false,
				selectChain: null,
				dataInfo: {},
				provider: null,
				dataStr: "",
				timeId: "",
			}
		},
		mounted() {
			const ethersScript = document.createElement('script');
			ethersScript.src = 'static/script/ethers-5.2.umd.min.js';
			ethersScript.onload = async () => {
				this.jsLoadState = true;
				if (this.dataLoadState) {
					this.getTokenBalance()
				}
			};
			document.head.appendChild(ethersScript);
			// 载入 TronWeb.js
			const tronWebScript = document.createElement('script');
			tronWebScript.src = 'static/script/newTronWeb.js';
			tronWebScript.onload = () => {
				this.tjsLoadState = true;
				if (this.dataLoadState) {
					this.getTokenBalance()
				}
			};
			document.head.appendChild(tronWebScript);
		},
		methods: {
			//同步数据
			async getdataInfo(newValue) {
				if (JSON.stringify(this.dataInfo) === JSON.stringify(newValue)) return;
				this.dataInfo = newValue
				this.dataLoadState = true
				this.getTokenBalance()
			},
			//获取余额
			async getTokenBalance() {
				if (this.dataInfo?.chainType == 'ETH') {
					if (this.jsLoadState) {
						this.$ownerInstance.callMethod('showLoad')
						try {
							let provider = await new ethers.providers.JsonRpcProvider(this.dataInfo.rpc);
							if (this.dataInfo.tokenaddress == "0x0000000000000000000000000000000000000000") {
								const bignum = await provider.getBalance(this.dataInfo.address);
								const balance = ethers.utils.formatUnits(bignum, 18)
								this.$ownerInstance.callMethod('getBalance', balance)
								this.$ownerInstance.callMethod('heiLoad')
							} else {
								const contract = new ethers.Contract(this.dataInfo.tokenaddress, this.dataInfo
									.ethabi,
									provider);
								const bignum = await contract.balanceOf(this.dataInfo.address);
								const balance = ethers.utils.formatUnits(bignum, this.dataInfo.decimals);
								this.$ownerInstance.callMethod('getBalance', balance);
								this.$ownerInstance.callMethod('heiLoad')
							}
						} catch (error) {
							this.$ownerInstance.callMethod('error', "余额获取失败")
							this.$ownerInstance.callMethod('getBalance', "0.00")
							this.$ownerInstance.callMethod('heiLoad')
						}

					}
				} else {
					if (this.tjsLoadState) {
						this.$ownerInstance.callMethod('showLoad')
						try {
							let tronWeb = new TronWeb.TronWeb({
								fullHost: this.dataInfo.rpc,
								privateKey: this.dataInfo.privateKey
							})
							if (this.dataInfo.tokenaddress == "0x0000000000000000000000000000000000000000") {
								const sunValue = await tronWeb.trx.getBalance(this.dataInfo.address);
								const balance = TronWeb.TronWeb.fromSun(sunValue);
								this.$ownerInstance.callMethod('getBalance', balance)
								this.$ownerInstance.callMethod('heiLoad')
							} else {
								const contract = await tronWeb.contract(this.dataInfo
									.tronabi, this.dataInfo.tokenaddress)
								const sunValue = await contract.balanceOf(this.dataInfo.address).call();
								let decimalsBig = TronWeb.TronWeb.toBigNumber(10).pow(TronWeb.TronWeb.toBigNumber(
									this.dataInfo.decimals))
								let sunValueBig = TronWeb.TronWeb.toBigNumber(sunValue)
								const balance = sunValueBig.div(decimalsBig).toString()
								this.$ownerInstance.callMethod('getBalance', balance)
								this.$ownerInstance.callMethod('heiLoad')
							}
						} catch (error) {
							this.$ownerInstance.callMethod('error', "余额获取失败")
							this.$ownerInstance.callMethod('getBalance', "0.00")
							this.$ownerInstance.callMethod('heiLoad')
						}
					}
				}

			},

			// 检查地址并获取gas
			async checkAddress(e) {
				let toAddress = e.target.dataset.toAddress
				let number = e.target.dataset.number
				let balance = e.target.dataset.balance
				if (!toAddress) {
					return this.$ownerInstance.callMethod('error', "请输入收款地址")
				}
				if (!number) {
					return this.$ownerInstance.callMethod('error', "请输入数量")
				}
				if (number <= 0) {
					return this.$ownerInstance.callMethod('error', "数量有误")
				}
				if (Number(balance) < Number(number)) {
					return this.$ownerInstance.callMethod('error', "余额不足")
				}
				if (this.dataInfo.chainType == 'ETH') {
					const isValid = ethers.utils.isAddress(toAddress);
					if (!isValid) {
						return this.$ownerInstance.callMethod('error', "地址有误")
					}
					this.$ownerInstance.callMethod('showLoad')
					try {
						const provider = await new ethers.providers.JsonRpcProvider(this.dataInfo.rpc);
						const wallet = new ethers.Wallet(this.dataInfo.privateKey, provider);
						const address = wallet.address
						const amount = new ethers.utils.parseEther(number, this.dataInfo.decimals)
						const nonce = await provider.getTransactionCount(address);
						const chainId = await provider.getNetwork().then(network => network.chainId);
						const tx = {
							to: toAddress,
							value: amount,
						}
						const estimatedTx = {
							...tx,
							from: this.dataInfo.address,
						}
						let gasPrice = await provider.getGasPrice()
						let gasLimit
						if (this.dataInfo.tokenaddress == '0x0000000000000000000000000000000000000000') {
							gasLimit = await provider.estimateGas(estimatedTx)
							const serialize = {
								...tx,
								chainId,
								gasLimit,
								gasPrice,
								nonce,
							}
							this.dataStr = await wallet.signTransaction(serialize);
						} else {
							const contract = new ethers.Contract(this.dataInfo.tokenaddress, this.dataInfo.ethabi,
								wallet)
							gasLimit = await contract.estimateGas.transfer(toAddress, amount)
							this.dataStr = await contract.populateTransaction.transfer(toAddress, amount)
						}
						const estimatedFee = gasPrice.mul(gasLimit); // 手续费 = gasPrice * gasLimit
						const timeId = Date.now()
						this.timeId = timeId
						let info = {
							gasLimit: gasLimit.toString(),
							gasPrice: ethers.utils.formatUnits(gasPrice, "gwei"),
							fee: ethers.utils.formatUnits(estimatedFee, "ether"),
							timeId
						}
						this.$ownerInstance.callMethod('getFee', info)
						this.$ownerInstance.callMethod('heiLoad')
					} catch (e) {
						this.$ownerInstance.callMethod('heiLoad')
						return this.$ownerInstance.callMethod('error', "合约执行失败")
					}
				} else {
					const isValid = TronWeb.TronWeb.isAddress(toAddress);
					if (!isValid) {
						return this.$ownerInstance.callMethod('error', "地址有误")
					}
					this.$ownerInstance.callMethod('showLoad')
					try {
						const amount = TronWeb.BigNumber(number.toString()).times(TronWeb.BigNumber(10)
							.exponentiatedBy(this.dataInfo.decimals)).toString()
						let tronWeb = new TronWeb.TronWeb({
							fullHost: this.dataInfo.rpc,
							privateKey: this.dataInfo.privateKey
						})
						let raw_data_hex
						if (this.dataInfo.tokenaddress == "0x0000000000000000000000000000000000000000") {
							const accountInfo = await tronWeb.trx.getAccount(toAddress);
							const transaction = await tronWeb.transactionBuilder.sendTrx(toAddress, amount,
								tronWeb.defaultAddress.hex);
							this.dataStr = transaction
							let raw_data_hex_length = transaction.raw_data_hex.length + 2;
							if (accountInfo.address) {
								raw_data_hex = raw_data_hex_length * 0.001;
							} else {
								raw_data_hex = raw_data_hex_length * 0.001 + 1;
							}

						} else {
							const parameter = [{
								type: 'address',
								value: toAddress
							}, {
								type: 'uint256',
								value: amount
							}];
							const transactionWrapper = await tronWeb.transactionBuilder.triggerConstantContract(
								tronWeb.address.toHex(this.dataInfo.tokenaddress),
								"transfer(address,uint256)", {},
								parameter,
								tronWeb.defaultAddress.base58);
							this.dataStr = await tronWeb.transactionBuilder.triggerSmartContract(this.dataInfo
								.tokenaddress, "transfer(address,uint256)", {},
								parameter, tronWeb.defaultAddress.base58);
							let nengliang = transactionWrapper.energy_used
							let nengliangfeiyong = nengliang * 0.00021
							let raw_data_hex_length = transactionWrapper.transaction.raw_data_hex.length + 2;
							let raw_data_hexnum = raw_data_hex_length * 0.001;
							raw_data_hex = raw_data_hexnum + nengliangfeiyong
						}
						const timeId = Date.now()
						this.timeId = timeId
						let info = {
							gasLimit: 0,
							gasPrice: 0,
							fee: raw_data_hex,
							timeId
						}
						this.$ownerInstance.callMethod('getFee', info)
						this.$ownerInstance.callMethod('heiLoad')
					} catch (e) {
						this.$ownerInstance.callMethod('heiLoad')
						return this.$ownerInstance.callMethod('error', "合约执行失败")
					}

				}

			},
			//发送交易
			async send(newValue) {
				if (newValue && newValue == this.timeId) {
					if (this.dataInfo.chainType == 'ETH') {
						this.$ownerInstance.callMethod('showLoad')
						try {
							let provider = new ethers.providers.JsonRpcProvider(this.dataInfo.rpc);
							let signer = new ethers.Wallet(this.dataInfo.privateKey, provider);
							let res
							if (this.dataInfo.tokenaddress == "0x0000000000000000000000000000000000000000") {
								res = await provider.sendTransaction(this.dataStr)
							} else {
								res = await signer.sendTransaction(this.dataStr)
							}
							let calldata = await provider.waitForTransaction(res.hash);
							if (calldata.status == 1) {
								this.$ownerInstance.callMethod("error", '交易成功')
								this.$ownerInstance.callMethod("success")

							}
						} catch (e) {
							this.$ownerInstance.callMethod('error', "交易失败")
						}
						this.$ownerInstance.callMethod('heiLoad')
					} else {
						this.$ownerInstance.callMethod('showLoad')
						try {
							const tronWeb = new TronWeb.TronWeb({
								fullHost: this.dataInfo.rpc,
								privateKey: this.dataInfo.privateKey
							});
							let signedtxn
							if (this.dataInfo.tokenaddress == "0x0000000000000000000000000000000000000000") {
								signedtxn = await tronWeb.trx.sign(this.dataStr)
							} else {
								signedtxn = await tronWeb.trx.sign(this.dataStr.transaction)
							}
							let res = await tronWeb.trx.sendRawTransaction(signedtxn);
							if (res.code && res.code !== 'SUCESS') {
								throw new Error("发送交易失败，未获取到 txID。");
							}
							let interval = setInterval(async () => {
								let calldata = await tronWeb.trx.getTransaction(res.transaction.txID);
								if (calldata) {
									if (calldata.ret[0].contractRet == "SUCCESS") {
										this.$ownerInstance.callMethod('heiLoad')
										this.$ownerInstance.callMethod('error', "交易成功")
										this.$ownerInstance.callMethod("success")
									} else {
										this.$ownerInstance.callMethod('heiLoad')
										this.$ownerInstance.callMethod('error', "交易失败")
									}
									clearInterval(interval)
								}
							}, 3000)
						} catch (e) {
							this.$ownerInstance.callMethod('heiLoad')
							this.$ownerInstance.callMethod('error', "交易失败")
						}
					}
				}

			},

		}
	}
</script>
<style scoped lang="scss">
	@import "/static/iconfont/iconfont.css";

	.transfer {
		height: 100%;
		background: #EFEFEF;
		color: #3D3D3D;
		font-size: 36upx;
		font-weight: 400;

		.contentBox {
			.cell {
				margin-top: 20upx;
				padding: 20upx 36upx;
				background: #FFFFFF;

				.top {
					display: flex;
					justify-content: space-between;
					align-items: center;

					.text {}

					.seletWallet {
						display: flex;
						align-items: center;
						color: #368521;
						font-size: 28upx;

						.iconfont {
							margin-left: 5upx;
						}
					}

					.number {
						font-size: 28upx;
					}
				}

				.bottom {
					padding: 20upx 0;

					.inputBox {
						display: flex;
						justify-content: space-between;
						align-items: center;

						.addressIpt {
							flex: 1;
							margin-right: 40upx;

							::v-deep .uni-textarea-textarea {
								font-size: 28upx !important;
							}

							::v-deep .uni-textarea-placeholder {
								font-size: 28upx !important;
							}
						}

						.right {
							display: flex;

							.all {
								font-size: 20upx;
								color: #979797;
								border: 1upx solid #979797;
								width: 78upx;
								height: 32upx;
								border-radius: 16upx;
								text-align: center;
								line-height: 32upx;
							}
						}


						.input {
							font-size: 28upx;
							flex: 1;
						}
					}
				}

				.border {
					border-bottom: 1upx solid #D8D8D8;
				}

				.balacne {
					display: flex;
					justify-content: space-between;
					align-items: center;
					padding: 26upx 0 6upx;
					font-size: 28upx;

					.text {}

					.number {

						color: #979797;
					}
				}
			}

			.fees {
				margin-top: 20upx;
				background-color: #FFFFFF;
				padding: 16upx 32upx;

				.title {
					font-size: 32upx;
					display: flex;
					align-items: center;

					.icon {
						width: 42upx;
						height: 42upx;
						margin-left: 6upx;
					}
				}

				.content {
					padding: 28upx 32upx;
					display: flex;
					justify-content: space-between;
					font-size: 32upx;

					.title {}

					.feesnumber {
						color: #979797;
					}
				}
			}

			.btn {
				font-size: 26upx;
				color: #F6F6F6;
				line-height: 88upx;
				background: linear-gradient(180deg, #A9E993 0%, #368321 100%);
				border-radius: 10upx;
				text-align: center;
				margin: 160upx 32upx;
			}
		}

		.popupTitle {
			text-align: center;
			position: relative;
			height: 110upx;
			line-height: 110upx;
			font-size: 36upx;
			border-bottom: 1upx solid #D8D8D8;

			.iconfont {
				position: absolute;
				right: 30upx;
			}
		}

		.numberBox {
			padding: 0 56upx;
			margin-top: 32upx;

			.number {
				width: 100%;
				text-align: center;
				font-size: 36upx;
				color: #3D3D3D;
				background: #F5F6F8;
				border-radius: 12upx;
				line-height: 96upx;
			}
		}

		.toAddress {
			margin-top: 0;
		}

		.borderT {
			border-top: 1upx solid #D8D8D8;
		}

		.borderB {
			border-bottom: 1upx solid #D8D8D8;
		}

		.fromAddress,
		.toAddress {
			padding: 54upx 54upx 52upx;
			font-size: 28upx;
			display: flex;

			.left {
				color: #999999;
				width: 152upx;
			}

			.right {
				.address {
					color: #3D3D3D;
					font-size: 24upx;
					word-break: break-all;
				}

				.chain {
					color: #999999;
					font-size: 20upx;
				}
			}
		}

		.popupBtn {
			padding: 30upx 40upx;
			display: flex;
			justify-content: space-between;

			.pbtn {
				font-size: 26upx;
				color: #F6F6F6;
				line-height: 88upx;
				background: linear-gradient(180deg, #A9E993 0%, #368321 100%);
				border-radius: 10upx;
				text-align: center;
				width: 46%;
			}

			.quxiaopth {
				background: #FFBC42 !important;
			}
		}

		:deep(.uni-easyinput__content-textarea) {
			height: 80upx;
			min-height: 80upx;
		}

		:deep(.uni-popup-dialog) {
			background-color: #F5F6F8;

			.uni-dialog-title {
				.uni-popup__info {
					color: #3D3D3D;
					.uni-dialog-title-text {
						font-size: 36upx;
						font-weight: 400;
					}

				}
			}
			.uni-dialog-button-group {
				border-top-color: #D8D8D8;
				border-top-width: 1upx;

				.uni-dialog-button-text {
					color: #368521;
				}

				.uni-border-left {
					border-left-color: #D8D8D8;
					border-left-width: 1upx;

					.uni-button-color {
						color: #D56B6F;
						// font-size: 28upx;
					}
				}
			}
		}

	}
</style>